package com.lzs.bootsafety.common.config.shiro;

import com.lzs.bootsafety.business.sys.entity.SysMenu;
import com.lzs.bootsafety.business.sys.entity.SysRole;
import com.lzs.bootsafety.business.sys.entity.SysUser;
import com.lzs.bootsafety.business.sys.service.SysMenuService;
import com.lzs.bootsafety.business.sys.service.SysRoleService;
import com.lzs.bootsafety.business.sys.service.SysUserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * @author  zhanshi Liu
 * @date    2020/03/22
 * @website www.jhmsona.cn
 */
//@Service
@Component
public class ShiroRealm extends AuthorizingRealm {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysMenuService sysMenuService;
    @Autowired
    private SysRoleService sysRoleService;
    /**
     * shiro认证通过后授权
     * @param principalCollection
     * @return
     *
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        // 权限信息对象info,用来存放查出的用户的所有的角色（role）及权限（perms）
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        SysUser sysUser =(SysUser) principalCollection.getPrimaryPrincipal();
        if (null == sysUser){
            return info;
        }
        List<SysRole> roleList = sysRoleService.getRoleByUserId(sysUser.getUserId());
        for (SysRole role : roleList) {
            info.addRole(role.getRoleName());
        }
        List<SysMenu> sysMenuList =null;
        if(sysUser.getUserType().equals("00")){
            sysMenuList = sysMenuService.getList(null);
        }else{
            sysMenuList = sysMenuService.getListMenuByUserId(sysUser.getUserId(),null);
        }
        if (!CollectionUtils.isEmpty(sysMenuList)){
            Set<String> permsSet = new HashSet<>();
            for (SysMenu sysMenu : sysMenuList) {
                String perms =null;
                if (sysMenu.getStatus()=="0" || "0".equals(sysMenu.getStatus())){
                    if (!StringUtils.isEmpty(perms = sysMenu.getPerms())){
                        permsSet.addAll(Arrays.asList(perms.trim().split(",")));
                    }
                }
            }
            info.setStringPermissions(permsSet);
        }
        return info;
    }


    /**
     * shiro认证方法
     * @param  token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        String username = (String) token.getPrincipal();
        SysUser sysUser = sysUserService.getUserByName(username);
        if (sysUser==null){
            return null;
        }
        if (sysUser.getStatus().equals("1")){
            throw new LockedAccountException("账号异常,请联系平台管理员");
        }
        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(sysUser,sysUser.getPassword(), ByteSource.Util.bytes(sysUser.getSalt()),getName());

        return simpleAuthenticationInfo;
    }
    /** 清空当前用户权限 */
    @Override
    public void clearCachedAuthorizationInfo(PrincipalCollection principals){
        super.clearCachedAuthorizationInfo(principals);
    }

    /**
     * 重写方法，清除当前用户的 认证缓存
     * @param principals
     */
    @Override
    public void clearCachedAuthenticationInfo(PrincipalCollection principals) {
        super.clearCachedAuthenticationInfo(principals);
    }

    @Override
    public void clearCache(PrincipalCollection principals) {
        super.clearCache(principals);
    }

    /**
     * 自定义方法：清除所有 授权缓存
     */
    public void clearAllCachedAuthorizationInfo() {
        getAuthorizationCache().clear();
    }

    /**
     * 自定义方法：清除所有 认证缓存
     */
    public void clearAllCachedAuthenticationInfo() {
        getAuthenticationCache().clear();
    }

    /**
     * 自定义方法：清除所有的  认证缓存  和 授权缓存
     */
    public void clearAllCache() {
        clearAllCachedAuthenticationInfo();
        clearAllCachedAuthorizationInfo();
    }
}
